#!/bin/bash

#set -x
#set -e

function usage() {
    echo "Usage: `basename $0` path kstart kincrement kend cstart cincrement cend repetitions"
    exit 1
}

# Paths
toolpath=./../tools/bin
algpath=./../algorithms/bin
repopath=./svn      #enter the path to your repository

# Settings
repair="0"                         #fixes up files if they dont match dimension
performstream="1"				   #1 = use streamkm++ 
performlocalsearch="1"			   #1 = use streamls
performbirch="1"				   #1 = use BIRCH
addtosvn="0"					   #1 = automatically adds centers and report to your repository
sendmail="0"					   #1 = send a notificationmail after script has finished
cleanup="1"                        #1 recommended to remove temporary files
birchattributetype="int"           #use int or double here
birchmemory="10"                    #default: birchmemory="5" which means, birch is using 5 percent of inputsize as parameter
addressaten="foo@bar.de"  #use commaseparated list here, no whitespaces


# better dont change something after this line unless you know what you do...

##################################################################################

# check for common errors
if [ -z "$1" -o ! -f "$1" -o $# -ne 8 ]; then
    usage
fi

if [ ! -d "$toolpath" ]; then
    echo "could not find directory $toolpath"
    exit 1
fi

if [ ! -d "$algpath" ]; then
    echo "could not find directory $algpath"
    exit 1
fi

if [ "$addtosvn" -eq 1 -a ! -d "$repopath" ]; then
    echo "could not find repository $repopath"
    exit 1
fi

# check for numerical values:
for i in `seq 2 1 8`; do
    p=`eval echo '$'$i`
    if [ -z "$p" ]; then
        echo "Param missing: $i"
		usage
        exit 1
    fi
    if [[ ! "$p" =~ '^[[:digit:]]+$' ]]; then
        echo "Param error: $p"
		usage
        exit 1
    fi
done

# check for non-zero incerements (would produce endless-loops otherwise)
if [ $3 -eq 0 ]; then
	echo "kinkremt should not be 0!"
	exit 1
fi
if [ $6 -eq 0 ]; then
	echo "cinkremt should not be 0!"
	exit 1
fi


# extract working directory
wdir="`dirname $1`"

# extract centers
k=`seq $2 $3 $4`

# extract coresetsize
c=`seq $5 $6 $7`

# extract number of repetitions
r="$8"

# 1. validate CSV-file and transform to WSV-file
wsvpath="$1".wsv
foo="`\"${toolpath}/csv2wsv\" $repair \"$1\" \"${wsvpath}\"`"
if [ ! $? -eq 0 ]; then
  echo ${foo}
  exit 1
fi
n=${foo%% *}
d=${foo##$n }


# 2. create report-file
date=`date`
datestamp=`date +"%FZ%H-%M"` 
report="${wdir}/report${datestamp}_`basename ${wsvpath}`.txt"

touch "$report"
cat > "$report" <<EOT
--- Clusteringreport ---

date: $date

--- Fileinformation ---

input file: $1
number of points: $n
dimension: $d

EOT

if [ ${performstream} -eq 1 ]; then
# 3. execute the streamKM++-algorithm and measure time
echo -e "----- streamKM++ -----\n\n" >> "$report"

for i in $c; do
  echo "--- coresetsize: $i" >> "$report"
  
  for j in $k; do
    echo "-- expected number of centres: $j" >> "$report"

    echo "- runtime" >> "$report"

    for l in `seq 1 1 $r`; do
      /usr/bin/time -f "%e" "${algpath}/stream" "$wsvpath" $n $j $d $i "${wdir}/streamcenters${i}_${j}_${l}.txt" `"${toolpath}/mt"` > /dev/null 2>> "$report" 
    done

# determine real number of centers    
    echo "- real number of centres" >> "$report"
    for l in `seq 1 1 $r`; do
	    foo=`wc -l "${wdir}/streamcenters${i}_${j}_${l}.txt"`
            realcenter=${foo%%"${wdir}/streamcenters${i}_${j}_${l}.txt"}           
	    echo $realcenter >> "$report"
    done

# 4. calculate costs
    echo -e "- costs" >> "$report"
    for l in `seq 1 1 $r`; do
      foo=`wc -l "${wdir}/streamcenters${i}_${j}_${l}.txt"`
      realcenter=${foo%%"${wdir}/streamcenters${i}_${j}_${l}.txt"}
      ${toolpath}/calculatecosts "$wsvpath" "${wdir}/streamcenters${i}_${j}_${l}.txt" $d $n $realcenter >> "$report"
    done
    echo -e "\n" >> "$report"
  done
  echo -e "\n" >> "$report"
done
fi

if [ ${performlocalsearch} -eq 1 ]; then
# 5. Execute streamLS-algorithmn and measure time
echo -e "\n----- streamLS -----" >> "$report"

for i in $c; do
  echo "--- chunksize: $i" >> "$report"
  
  for j in $k; do
    echo "-- expected number of centres: $j" >> "$report"

    echo "- runtime" >> "$report"

    for l in `seq 1 1 $r`; do
      echo `"${toolpath}/mt"` > "${algpath}/seeds"
      /usr/bin/time -f "%e" "${algpath}/localsearch" $j $j $n $d "${wsvpath}" 0 "${wdir}/localsearchcenters${i}_${j}_${l}.txt" $i > /dev/null 2>> "$report"
    done

# determine real number of centers    
    echo "- real number of centres" >> "$report"
    for l in `seq 1 1 $r`; do
	    foo=`wc -l "${wdir}/localsearchcenters${i}_${j}_${l}.txt"`
            realcenter=${foo%%"${wdir}/localsearchcenters${i}_${j}_${l}.txt"}           
	    echo $realcenter >> "$report"
    done

# 6. calculte costs for streamLS
    echo "- costs" >> "$report"
    for l in `seq 1 1 $r`; do
      foo=`wc -l "${wdir}/localsearchcenters${i}_${j}_${l}.txt"`
      realcenter=${foo%%"${wdir}/localsearchcenters${i}_${j}_${l}.txt"}     
      ${toolpath}/calculatecosts "$wsvpath" "${wdir}/localsearchcenters${i}_${j}_${l}.txt" $d $n $realcenter >> "$report"
    done
    echo -e "\n" >> "$report"
  done
  echo -e "\n" >> "$report"
done
fi

if [ ${performbirch} -eq 1 ]; then
# 7. execute BIRCH and measure time
cp "${algpath}/Birch.exe" "${wdir}"
cd "${wdir}"
echo -e "\n----- BIRCH -----" >> "$report"

# create Proj-file
echo -n "$d " > "${wdir}/proj"
for i in `seq 1 1 $(($d - 1))`; do
  printf "x${i} " >> "${wdir}/proj"
done
echo "x${d}" >> "${wdir}/proj"  


# create Scheme-file
echo "type Generic-Schema ascii
comment //
separator ' '" > "${wdir}/scheme"
for i in `seq 1 1 $d`; do
  echo "attr x${i} ${birchattributetype}" >> "${wdir}/scheme"
done

for j in $k; do

  echo -e "expected number of centres: $j\n\n- runtime" >> "$report"

# create Para-files
du=`du -b "${wsvpath}.b"`
bytesize=${du%%"${wsvpath}.b"}
bytesizepercent=$((${bytesize} / 100 * ${birchmemory}))
bytesizepercent2=$((${bytesizepercent} / 100 * ${birchmemory}))
cat > "${wdir}/para$j" <<EOT
0
$bytesizepercent
$bytesizepercent2
$bytesizepercent2
$bytesizepercent2

0
EOT

for i in `seq 1 1 $(($d - 1))`; do
  echo -n "1 " >> "${wdir}/para$j"
done
echo "1" >> "${wdir}/para$j"

for i in `seq 1 1 $(($d - 1))`; do
  echo -n "0 " >> "${wdir}/para$j"
done
echo -e "0\n" >> "${wdir}/para$j"

if [ $d -lt 50 ]; then
    echo -e "1024\n" >> "${wdir}/para$j"
else
    echo -e "2048\n" >> "${wdir}/para$j"
fi

cat >> "${wdir}/para$j" <<EOT
4
0
0
0
4
0.25

2000

0
0
EOT

for i in `seq 1 1 $(($d - 1))`; do
  echo -n "100 " >> "${wdir}/para$j"
done
cat >> "${wdir}/para$j" <<EOT
100

$j
0
0
1
2
0
1
0
1
EOT


# execute BIRCH
cd ${wdir}
	/usr/bin/time -f "%e" ${wdir}/Birch.exe para$j scheme proj `basename ${wsvpath}`.b > /dev/null 2>> "$report"

if [ $? -eq 0 ]; then
  # extract centers
  cat "${wdir}/para$j+scheme+proj+`basename ${wsvpath}`.b-0-cluster" | sed -n -e 's/^[^[:space:]]*[[:space:]]\+\(.*\)\([[:space:]]\+.\+\)\{2\}$/1 \1/; T; s/[[:space:]]\+/ /gp' > ${wdir}/birchcenters${j}.txt

  # determine real number of centers   
  echo "- real number of centres" >> "$report"
  foo=`wc -l "${wdir}/birchcenters${j}.txt"`
  realcenter=${foo%%"${wdir}/birchcenters${j}.txt"}           
  echo $realcenter >> "$report"
  
  # calculate costs for birch
  echo -e "\n- costs" >> "$report"
  foo=`wc -l "${wdir}/birchcenters${j}.txt"`
  realcenter=${foo%%"${wdir}/birchcenters${j}.txt"}     
  ${toolpath}/calculatecosts "$wsvpath" "${wdir}/birchcenters${j}.txt" $d $n $realcenter >> "$report" 

  # delete temporary files of birch
  rm "${wdir}/Tmp-cluster"
  rm "${wdir}/para$j+scheme+proj+`basename ${wsvpath}`.b-0-cluster"
  rm "${wdir}/para$j+scheme+proj+`basename ${wsvpath}`.b-log"
else
  echo "BIRCH failed!" >> "$report"
fi

done  # for j in $k
fi

# 9. finish report-file
echo -e "\n-------------------------
This run was performed on $HOSTNAME by $USER." >> "$report"


# 10. zip centers
if [ -f "${wdir}/centers.tar" ]; then
  rm "${wdir}/centers.tar"
fi
touch "${wdir}/centers.tar"
if [ $performstream -eq 1 ]; then
  for i in $c; do
    for j in $k; do
      for l in `seq 1 1 $r`; do
        tar -C "${wdir}" --remove-files -rf "${wdir}/centers.tar" "streamcenters${i}_${j}_${l}.txt"
      done
    done
  done
fi

if [ $performlocalsearch -eq 1 ]; then
  for i in $c; do
    for j in $k; do
      for l in `seq 1 1 $r`; do
        tar -C "${wdir}" --remove-files -rf "${wdir}/centers.tar" "localsearchcenters${i}_${j}_${l}.txt"
      done
    done
  done
fi

if [ $performbirch -eq 1 ]; then
  for l in $k; do
    tar -C "${wdir}" --remove-files -rf "${wdir}/centers.tar" "birchcenters${l}.txt"   
  done
fi

if [ -f "${wdir}/centers.tar.gz" ]; then
  rm "${wdir}/centers.tar.gz"
fi
gzip "${wdir}/centers.tar"

# 11. tidy up
if [ ${cleanup} -eq 1 ]; then
  rm "$wsvpath"
  rm "$wsvpath.b"
  if [ $performbirch -eq 1 ]; then
    rm "${wdir}/proj"
    rm "${wdir}/scheme"
    rm "${wdir}/Birch.exe"
    for i in $k; do
      rm "${wdir}/para$i"
    done
  fi
fi

# 12. send email with results
if [ ${sendmail} -eq 1 ]; then
  cat "$report" | mail -s "Testergebnisse vom ${date}" "$addressaten"
fi

# 13. add results to svn
if [ ${addtosvn} -eq 1 ]; then
  newdir="${repopath}/trunk/results/${datestamp}_`basename ${wsvpath}`"
  mkdir "${newdir}"
  mv "${wdir}/centers.tar.gz" "${newdir}"
  mv "$report" "${newdir}"
  svn up "${repopath}" 
  svn add "${newdir}"
  svn ci "${newdir}" -m"Testergebnisse von ${date}"
fi

exit 0

################## 
